package dontCare.gwtester.client.gwt.leakyAbstraction;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.IntegerBox;
import com.google.gwt.user.client.ui.Widget;

import dontCare.gwtester.client.tool.SourceUrl;
import dontCare.gwtester.client.tool.UnitWidget;

public class ByteArrayToString extends UnitWidget{
	private static ByteArrayToStringUiBinder uiBinder = GWT.create(ByteArrayToStringUiBinder.class);
	interface ByteArrayToStringUiBinder extends UiBinder<Widget, ByteArrayToString> {}

	@UiField FlexTable table;
	@UiField IntegerBox start;
	@UiField IntegerBox end;
	
	@UiHandler("showUnit") void clickShowUnit(ClickEvent c){
		if(!validInput()){
			return;
		}
		
		int startValue = start.getValue();
		int endValue = end.getValue();

		table.removeAllRows();
		byte[] bytes = new byte[1];
		for(int i=startValue; i<=endValue; i++){
			try{
				bytes[0] = (byte)i;
				String str = new String(bytes);
				table.setText((i-startValue)/8, (i-startValue)%8, i+" → "+str);
			}catch(Exception e){
				table.setText((i-startValue)/8, (i-startValue)%8, i+" occur "+e.getMessage());
			}
		}
	}
	
	@UiHandler("showAll") void clickShowAll(ClickEvent c){
		if(!validInput()){
			return;
		}

		int startValue = start.getValue();
		int endValue = end.getValue();
		
		table.removeAllRows();
		byte[] bytes = new byte[endValue-startValue+1];
		for(int i=startValue; i<=endValue; i++){
			bytes[i-startValue] = (byte)i;
		}
		try{
			table.setText(0, 0, new String(bytes));
		}catch(Exception e){
			table.setText(0, 0, e.getMessage());
		}
	}
	
	private boolean validInput(){
		try {
			start.getValueOrThrow();
			end.getValueOrThrow();
		} catch (ParseException e1) {
			Window.alert("請乖乖輸入數字好唄......");
			return false;
		}
		//XXX 其他防呆懶得做了
		return true;
	}
	
	public ByteArrayToString(){
		this.initWidget(uiBinder.createAndBindUi(this));
	}
	
	@Override
	public List<String> getSourceUrl() {
		ArrayList<String> result = new ArrayList<String>();
		result.add(SourceUrl.genJava(this.getClass()));
		result.add(SourceUrl.genUiXml(this.getClass()));
		return result;
	}

	@Override
	public HTML getDescription() {
		return new HTML(
			"這是在《Java Puzzle》的謎題 18 遇到特定 byte[] 轉換成 String 時會產生 exception。<br/>" +
			"這個問題在 Development Mode 運作正常，在 Product Mode 才會出錯。"
		);
	}

	@Override
	public String getName() {
		return "Byte[] 轉 String 問題";
	}
}
